package cn.com.open.itembank.service;

import cn.com.open.itembank.common.enums.AnswerType;
import cn.com.open.itembank.dto.*;
import cn.com.open.itembank.entity.CourseItemBank;
import cn.com.open.itembank.entity.Question;
import cn.com.open.itembank.exception.PoiException;
import net.lingala.zip4j.exception.ZipException;

import java.io.IOException;
import java.util.List;
import java.util.Map;


/**
 * Created by lucky on 2017/9/1.
 */
public interface ItemService {

    /**
     * 判断题库和试题是否存在关系.
     *
     * @param itemBankId 题库id
     * @param id         试题id
     * @return the boolean
     */
    boolean checkItemBankQuestionRelation(String itemBankId, String id);

    /**
     * 获取试题基本信息.
     *
     * @param id 试题id
     * @return the item
     */
    Question getItem(String id);

    /**
     * 获得指定题库下指定试题的试题模型(不根据type==2转换).
     *
     * @param itemBankId 题库id
     * @param id         试题id
     * @param type       获取答案类型：0，全部；1，试题；2，答案
     * @return 试题模型 return model
     */
    ReturnModel getItemBankQuestion(String itemBankId, String id, AnswerType type);

    /**
     * 获得指定题库下指定试题的试题模型.
     *
     * @param itemBankId    题库id
     * @param id            试题id
     * @param includeAnswer 是否包含答案
     * @return 试题模型 return model
     */
    QuestionModel getItemBankQuestionForPaper(String itemBankId, String id, boolean includeAnswer);

    /**
     * 根据试题ID查询试题应用类别信息.
     *
     * @param id 试题ID
     * @return 试题应用类别信息 question category
     */
    ReturnModel getQuestionCategory(String id);

    /**
     * 随机获取指定题库指定题型指定数量的试题集合.
     *
     * @param itemBankId     题库id
     * @param questionTypeId 题型id
     * @param cnt            获取数量
     * @return 试题id集合 random questions by item bank id and q type
     */
    ReturnModel getRandomQuestionsByItemBankIdAndQType(String itemBankId, String questionTypeId, int cnt);

    /**
     * 根据题库id获取指定题库下试题按照题型，难度，应用类别的数量统计列表.
     *
     * @param itemBankId 题库id
     * @return 数量统计列表 question stat by item bank id
     */
    ReturnModel getQuestionStatByItemBankId(String itemBankId);

    /**
     * 根据题库id获取指定题库下试题按照应用类别的数量统计列表.
     *
     * @param itemBankId 题库id
     * @return 数量统计列表 question stat for category by item bank id
     */
    ReturnModel getQuestionStatForCategoryByItemBankId(String itemBankId);

    /**
     * 根据试题数量查询模型获取指定条件下试题数量（策略用）.
     *
     * @param filterModels the filter model
     * @return the question count for rules check
     */
    Map<String, Integer> getQuestionCountForRulesCheck(Map<String, QuestionCountFilterModel> filterModels);

    /**
     * 根据试题数量查询模型获取指定条件下试题（策略组卷用）.
     *
     * @param filterModels the filter model
     * @return the question count for rules check
     */
    Map<String, List<RuleQuestionModel>> getQuestionForRule(Map<String, QuestionCountFilterModel> filterModels);

    /**
     * 根据题库id，题型id，所属类别id查询试题id列表（策略用）.
     *
     * @param itemBankId     题库id
     * @param typeCategories 题型，类别map
     * @return the questions by categories for rules
     */
    Map<String, List<String>> getQuestionsByCategoriesForRules(String itemBankId, Map<String, String> typeCategories);

    /**
     * 根据题库id获取指定题库下指定题型的试题按照给定的章节,应用类别统计的难中易三档题数列表.
     *
     * @param itemBankId 题库id
     * @param cntModel   统计参数模型
     * @return the question difficulty stat by item bank id
     */
    ReturnModel getQuestionDifficultyStatByItemBankId(String itemBankId, DifficultyCountModel cntModel);

    /**
     * 根据试题id列表获取策略检查用的试题信息列表（策略检查必选和例题用）.
     *
     * @param itemIds the item ids
     * @return the question info for rule check
     */
    List<RuleCheckQuestionInfo> getQuestionInfoForRuleCheck(Map<String, Boolean> itemIds);

    /**
     * 新增试题
     * v4版本 I8不支持汉字模式；I30只支持sx-xx
     *
     * @param questionModel 试题录入模型
     * @param source        来源：0，内部；1，外部
     * @param sourceType    来源类型：0，试题录入；1，试卷录入
     * @param inputType     录题方式：0，手工录入；1，文件导入
     * @param importType    导入方式：0，无；1，word导入；2，excel导入
     * @param appKey        app key
     * @return the return model
     */
    ReturnModel addQuestion(QuestionModel questionModel, int source, int sourceType, int inputType, int importType, String appKey);

    /**
     * 审核试题(只能修改私有状态的试题).
     *
     * @param itemBankId  题库id
     * @param id          试题id
     * @param checkStatus 目标审核状态：true 审核通过；false  审核拒绝
     * @param appKey      appkey
     * @return the return model
     */
    ReturnModel updateCheckStatus(String itemBankId, String id, boolean checkStatus, String appKey);

    /**
     * 停启用试题(只能修改私有状态的试题).
     *
     * @param itemBankId 题库id
     * @param id         试题id
     * @param appKey     appkey
     * @return the return model
     */
    ReturnModel updateStatus(String itemBankId, String id, String appKey);

    /**
     * 临时删除试题
     *
     * @param itemBankId 题库id
     * @param id         试题id
     * @param appKey     appkey
     * @return return model
     */
    ReturnModel deleteQuestion(String itemBankId, String id, String appKey);

    /**
     * 批量临时删除试题
     *
     * @param itemBankId 题库id
     * @param idList     试题id集合
     * @param appKey     appkey
     * @return the return model
     */
    ReturnModel deleteQuestionList(String itemBankId, List<String> idList, String appKey);

    /**
     * 恢复试题
     *
     * @param itemBankId 题库id
     * @param id         试题id
     * @param appKey     appkey
     * @return the return model
     */
    ReturnModel recover(String itemBankId, String id, String appKey);

    /**
     * 批量恢复试题
     *
     * @param itemBankId 题库id
     * @param idList     试题id集合
     * @param appKey     appkey
     * @return the return model
     */
    ReturnModel recoverList(String itemBankId, List<String> idList, String appKey);

    /**
     * 彻底删除试题
     *
     * @param itemBankId 题库id
     * @param id         试题id
     * @param appKey     appkey
     * @return the return model
     */
    ReturnModel removeQuestion(String itemBankId, String id, String appKey);

    /**
     * 批量彻底删除试题
     *
     * @param itemBankId 题库id
     * @param idList     试题id集合
     * @param appKey     appkey
     * @return the return model
     */
    ReturnModel removeQuestionList(String itemBankId, List<String> idList, String appKey);

    /**
     * 试题列表
     *
     * @param filterModelDto 试题筛选模型
     * @param isOuter        是否外部调用
     * @param isGetContent   是否获取试题内容
     * @return return model
     */
    ReturnModel getList(FilterModelDto filterModelDto, Boolean isOuter, Boolean isGetContent);

    /**
     * 获取试题回收站列表.
     *
     * @param filterModelDto 筛选模型
     * @return the return model
     */
    ReturnModel getRycleBinList(FilterModelDto filterModelDto);

    /**
     * 试题导出.
     *
     * @param filterModelDto the filter model dto
     * @return the return model
     * @throws PoiException the poi exception
     * @throws ZipException the zip exception
     * @throws IOException  the io exception
     */
    ReturnModel exportQuestion(FilterModelDto filterModelDto) throws PoiException, ZipException, IOException;

    /**
     * Update question return model.
     *
     * @param itemBankId    the item bank id
     * @param questionId    the question id
     * @param questionModel the question model
     * @param appKey        the app key
     * @return the return model
     */
    ReturnModel updateQuestion(String itemBankId, String questionId, QuestionModel questionModel, String appKey);

    /**
     * 试题状态批量修改.
     *
     * @param itemBankId  题库id
     * @param statusModel 状态模型
     * @param appKey      appkey
     * @return the return model
     */
    ReturnModel batchUpdateStatus(String itemBankId, UpdateQuestionStatus statusModel, String appKey);

    /**
     * 共享试题.
     *
     * @param sourceItemBankId 源题库id
     * @param targetItemBank   目标题库模型
     * @param chapterRelation  旧新章节对照map
     * @return the return model
     */
    ReturnModel shareQuestion(String sourceItemBankId, CourseItemBank targetItemBank, Map<String, String> chapterRelation);

    /**
     * 获取试题模型
     *
     * @param itemBankId 题库ID
     * @return
     */
    ReturnModel getQuestionModel(String itemBankId);

}
